package net.xdclass.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import lombok.extern.slf4j.Slf4j;
import net.xdclass.VO.UserVO;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.enums.SendCodeEnum;
import net.xdclass.fegin.CouponFeignService;
import net.xdclass.interceptor.LoginInterceptor;
import net.xdclass.mapper.UserMapper;
import net.xdclass.model.LoginUser;
import net.xdclass.model.UserDO;
import net.xdclass.request.NewUserCouponRequest;
import net.xdclass.request.UserLoginRequest;
import net.xdclass.request.UserRegisterRequest;
import net.xdclass.service.NotifyService;
import net.xdclass.service.UserService;
import net.xdclass.util.CommonUtil;
import net.xdclass.util.JWTUtil;
import net.xdclass.util.JsonData;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import springfox.documentation.spring.web.json.Json;

import java.util.Date;
import java.util.List;

/**
 * @author guangyang
 * @since 2023-01-24
 **/
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private CouponFeignService couponFeignService;

    @Autowired
    private NotifyService notifyService;

    @Autowired
    private UserMapper userMapper;

    @Override
    @Transactional(rollbackFor=Exception.class,propagation= Propagation.REQUIRED)//添加事务中断则完全回滚
    //@GlobalTransactional
    public JsonData register(UserRegisterRequest request) {
        boolean checkCode=false;
        if (StringUtils.isNotBlank(request.getMail())){
            checkCode = notifyService.checkCode(SendCodeEnum.USER_REGISTER, request.getMail(), request.getCode());
        }
        if (!checkCode){
            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
        }
        //添加userDO实例
        UserDO userDO=new UserDO();
        BeanUtils.copyProperties(request,userDO);
//      设置时间
        userDO.setCreateTime(new Date());
//      加盐
        userDO.setSecret("$1$"+ CommonUtil.getStringNumRandom(8));
//      密码+盐处理
        String cryptPwd = Md5Crypt.md5Crypt(request.getPwd().getBytes(), userDO.getSecret());
        userDO.setPwd(cryptPwd);


//       账号唯一性检查
        if (checkUnique(userDO.getMail())){
          int insert = userMapper.insert(userDO);
          log.info("{}注册成功{}",insert,userDO.toString());
//         新账户福利发放
          userRegisterInitTask(userDO);

          return JsonData.buildSuccess();
        }else {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_REPEAT);
        }
    }

    /**
     * 用户登录
     * @param request
     * @return
     */
    @Override
    public JsonData login(UserLoginRequest request) {
        List<UserDO> userDOList = userMapper.selectList(new QueryWrapper<UserDO>().eq("mail", request.getMail()));
        if (userDOList!=null&&userDOList.size()==1){
//            已经注册
            UserDO userDO = userDOList.get(0);
            String requestPwd = Md5Crypt.md5Crypt(request.getPwd().getBytes(), userDO.getSecret());
            if (requestPwd.equals(userDO.getPwd())){
                //登录成功生成token
                //生成loginUser对象
                LoginUser loginUser = new LoginUser();
                BeanUtils.copyProperties(userDO, loginUser);
                //调用方法生成token
                String token = JWTUtil.geneJsonWebToken(loginUser);
                return JsonData.buildSuccess(token);
            }else {
                return JsonData.buildSuccess(BizCodeEnum.ACCOUNT_PWD_ERROR);
            }

        }else {
            return JsonData.buildSuccess(BizCodeEnum.ACCOUNT_UNREGISTER);
        }
    }

    /**
     * 获取用户信息的方法
     * @return 用户信息对象
     */
    @Override
    public JsonData detail() {
        //获取token的对象
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
//      通过id获取userDO
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().eq("id", loginUser.getId()));
        if (userDO==null){
            throw new RuntimeException("用户不存在或已注销");
        }
        //      userDO->userVO后返回
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userDO,userVO);
        return JsonData.buildSuccess(userVO);
    }

    /**
     * 校验账号唯一性
     * @param mail 邮箱
     * @return 是否存在
     */
    private boolean checkUnique(String mail) {
        QueryWrapper<UserDO> mail1 = new QueryWrapper<UserDO>().eq("mail", mail);
        List<UserDO> userDOS = userMapper.selectList(mail1);
        return userDOS.size() == 0;
    }

    /**
     * 用户注册，初始化福利信息
     *
     * @param userDO
     */
    private void userRegisterInitTask(UserDO userDO) {
        NewUserCouponRequest request = new NewUserCouponRequest();
        request.setName(userDO.getName());
        request.setUserId(userDO.getId());
        JsonData jsonData = couponFeignService.addNewUserCoupon(request);
        log.info("发放新用户注册优惠券：{},结果:{}",request.toString(),jsonData.toString());

    }

}

